package com.anandsoftware.application;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import org.apache.commons.validator.routines.UrlValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ApplicationContext {

	private final Logger LOG = LoggerFactory
			.getLogger(ApplicationContext.class);

	public static String DEFAULT_TABLE_NAME;
	public static String DEFAULT_IV;
	public static String DEFAULT_KEY;
	public static int KEY_LENGTH = 8;
	public static int IV_LENGTH = 8;
	public static String version;
	public static String AUTHENTICATE_SERVICE_REQUEST_URL;
	public static String ACCESS_SERVICE_REQUEST_URL;
	public static String TERMINATE_SERVICE_REQUEST_URL;
	public static String REGISTRATION_SERVICE_REQUEST_URL;
	public static String UPDATE_SERVICE_REQUEST_URL;
	public static String AUTHENTICATE_SERVICE_TOKEN;
	public static String REQUEST_ACCESS_TOKEN;
	public static String TERMINATE_ACCESS_TOKEN;
	public static String REGISTERATION_SERVICE_TOKEN;
	public static String UPDATE_SERVICE_TOKEN;

	private String cause = "Property Not Found :";

	public ApplicationContext(String configurationFilePath)
			throws ApplicationContextInitializationFailed,
			FileNotFoundException, IOException {

		UrlValidator urlValidator = new UrlValidator();

		LOG.info("Loading Properties File - " + configurationFilePath);
		Properties prop = new Properties();
		prop.load(new FileInputStream(configurationFilePath));

		DEFAULT_TABLE_NAME = prop.getProperty("DEFAULT.TABLE.NAME");
		if (DEFAULT_TABLE_NAME == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "DEFAULT.TABLE.NAME");
		}

		DEFAULT_IV = prop.getProperty("DEFAULT.IV");
		if (DEFAULT_IV == null) {
			DEFAULT_IV = "12345678";
		} else if (DEFAULT_IV.length() != IV_LENGTH) {
			throw new ApplicationContextInitializationFailed(
					"Improper Length :" + "DEFAULT.IV" + " (Must be "
							+ IV_LENGTH + ")");
		}

		DEFAULT_KEY = prop.getProperty("DEFAULT.KEY");
		if (DEFAULT_KEY == null) {
			DEFAULT_KEY = "12345678";
		} else if (DEFAULT_KEY.length() != KEY_LENGTH) {
			throw new ApplicationContextInitializationFailed(
					"Improper Length :" + "DEFAULT.KEY" + " (Must be "
							+ KEY_LENGTH + ")");
		}

		version = prop.getProperty("VERSION");
		if (version == null) {
			throw new ApplicationContextInitializationFailed(cause + "VERSION");
		} else {
			try {
				Double.parseDouble(version.trim());
			} catch (Exception e) {
				throw new ApplicationContextInitializationFailed(
						"Not a correct Version :" + " VERSION");
			}
		}
		version = "v" + version;

		AUTHENTICATE_SERVICE_REQUEST_URL = prop
				.getProperty("AUTHENTICATE.SERVICE.REQUEST.URL");
		if (AUTHENTICATE_SERVICE_REQUEST_URL == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "AUTHENTICATE.SERVICE.REQUEST.URL");
		} else if (!urlValidator.isValid(AUTHENTICATE_SERVICE_REQUEST_URL
				.trim())) {
			throw new ApplicationContextInitializationFailed("Invalid Url :"
					+ "AUTHENTICATE.SERVICE.REQUEST.URL");
		}

		ACCESS_SERVICE_REQUEST_URL = prop
				.getProperty("ACCESS.SERVICE.REQUEST.URL");
		if (ACCESS_SERVICE_REQUEST_URL == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "ACCESS.SERVICE.REQUEST.URL");
		} else if (!urlValidator.isValid(ACCESS_SERVICE_REQUEST_URL.trim())) {
			throw new ApplicationContextInitializationFailed("Invalid Url :"
					+ "ACCESS.SERVICE.REQUEST.URL");
		}

		TERMINATE_SERVICE_REQUEST_URL = prop
				.getProperty("TERMINATE.SERVICE.REQUEST.URL");
		if (TERMINATE_SERVICE_REQUEST_URL == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "TERMINATE.SERVICE.REQUEST.URL");
		} else if (!urlValidator.isValid(TERMINATE_SERVICE_REQUEST_URL.trim())) {
			throw new ApplicationContextInitializationFailed("Invalid Url :"
					+ "TERMINATE.SERVICE.REQUEST.URL");
		}

		REGISTRATION_SERVICE_REQUEST_URL = prop
				.getProperty("REGISTRATION.SERVICE.REQUEST.URL");
		if (REGISTRATION_SERVICE_REQUEST_URL == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "REGISTRATION.SERVICE.REQUEST.URL");
		} else if (!urlValidator.isValid(REGISTRATION_SERVICE_REQUEST_URL
				.trim())) {
			throw new ApplicationContextInitializationFailed("Invalid Url :"
					+ "REGISTRATION.SERVICE.REQUEST.URL");
		}

		UPDATE_SERVICE_REQUEST_URL = prop
				.getProperty("UPDATE.SERVICE.REQUEST.URL");
		if (UPDATE_SERVICE_REQUEST_URL == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "UPDATE.SERVICE.REQUEST.URL");
		} else if (!urlValidator.isValid(UPDATE_SERVICE_REQUEST_URL.trim())) {
			throw new ApplicationContextInitializationFailed("Invalid Url :"
					+ "UPDATE_SERVICE_REQUEST_URL");
		}

		AUTHENTICATE_SERVICE_TOKEN = prop
				.getProperty("AUTHENTICATE.SERVICE.TOKEN");
		if (AUTHENTICATE_SERVICE_TOKEN == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "AUTHENTICATE.SERVICE.TOKEN");
		}

		REQUEST_ACCESS_TOKEN = prop.getProperty("REQUEST.ACCESS.TOKEN");
		if (REQUEST_ACCESS_TOKEN == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "REQUEST.ACCESS.TOKEN");
		}

		TERMINATE_ACCESS_TOKEN = prop.getProperty("TERMINATE.ACCESS.TOKEN");
		if (TERMINATE_ACCESS_TOKEN == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "TERMINATE.ACCESS.TOKEN");
		}

		REGISTERATION_SERVICE_TOKEN = prop
				.getProperty("REGISTERATION.SERVICE.TOKEN");
		if (REGISTERATION_SERVICE_TOKEN == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "REGISTERATION.SERVICE.TOKEN");
		}

		UPDATE_SERVICE_TOKEN = prop.getProperty("UPDATE.SERVICE.TOKEN");
		if (UPDATE_SERVICE_TOKEN == null) {
			throw new ApplicationContextInitializationFailed(cause
					+ "UPDATE.SERVICE.TOKEN");
		}

		DEFAULT_TABLE_NAME = DEFAULT_TABLE_NAME.trim();

		DEFAULT_IV = DEFAULT_IV.trim();
		DEFAULT_KEY = DEFAULT_KEY.trim();

		version = version.trim();

		AUTHENTICATE_SERVICE_REQUEST_URL = AUTHENTICATE_SERVICE_REQUEST_URL
				.trim();
		ACCESS_SERVICE_REQUEST_URL = ACCESS_SERVICE_REQUEST_URL.trim();
		TERMINATE_SERVICE_REQUEST_URL = TERMINATE_SERVICE_REQUEST_URL.trim();
		REGISTRATION_SERVICE_REQUEST_URL = REGISTRATION_SERVICE_REQUEST_URL
				.trim();
		UPDATE_SERVICE_REQUEST_URL = UPDATE_SERVICE_REQUEST_URL.trim();

		AUTHENTICATE_SERVICE_TOKEN = AUTHENTICATE_SERVICE_TOKEN.trim() + "=";
		TERMINATE_ACCESS_TOKEN = TERMINATE_ACCESS_TOKEN.trim() + "=";
		REQUEST_ACCESS_TOKEN = REQUEST_ACCESS_TOKEN.trim() + "=";
		REGISTERATION_SERVICE_TOKEN = REGISTERATION_SERVICE_TOKEN.trim() + "=";
		UPDATE_SERVICE_TOKEN = UPDATE_SERVICE_TOKEN.trim() + "=";

		LOG.info("All Properties Loaded ");
		LOG.info("[Table : " + DEFAULT_TABLE_NAME + ",IV : " + DEFAULT_IV
				+ ",Key : " + DEFAULT_KEY + ",version : " + version
				+ ",Auth URL : " + AUTHENTICATE_SERVICE_REQUEST_URL
				+ ",Update URL : " + UPDATE_SERVICE_REQUEST_URL
				+ ",Register URL : " + REGISTRATION_SERVICE_REQUEST_URL
				+ ",Terminate URL : " + TERMINATE_SERVICE_REQUEST_URL
				+ ",Access Token : " + REQUEST_ACCESS_TOKEN + ",Auth Token : "
				+ AUTHENTICATE_SERVICE_TOKEN + ",Register Token : "
				+ REGISTERATION_SERVICE_TOKEN + ",Update Token : "
				+ UPDATE_SERVICE_TOKEN);
	}

}
